package com.jingyanzi.member.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jingyanzi.channel.domain.ChannelTypeDO;
import com.jingyanzi.member.api.ChannelClientAPI;
import com.jingyanzi.member.api.DicClientAPI;
import com.jingyanzi.member.dao.MCustomerMapper;
import com.jingyanzi.member.domain.CustomerDO;
import com.jingyanzi.member.domain.CustomerExtraDO;
import com.jingyanzi.member.domain.CustomerFamilyDO;
import com.jingyanzi.member.domain.LeadDO;
import com.jingyanzi.member.domain.result.ResultDO;
import com.jingyanzi.member.domain.result.ResultSupport;
import com.jingyanzi.member.entity.MCustomer;
import com.jingyanzi.member.entity.MCustomerExample;
import com.jingyanzi.member.entity.MCustomerExample.Criteria;
import com.jingyanzi.member.query.CustomerQueryDO;
import com.jingyanzi.member.query.LeadQueryDO;
import com.jingyanzi.member.service.IAnalysisService;
import com.jingyanzi.member.service.ICustomerExtraService;
import com.jingyanzi.member.service.ICustomerFamilyService;
import com.jingyanzi.member.service.ICustomerService;
import com.jingyanzi.member.util.BeanUtilsExtends;
import com.jingyanzi.member.util.MemberConstant;
import com.jingyanzi.member.util.StaticDicUtil;
import com.jingyanzi.sys.domain.DictionariesDO;

@Service("customerService")
public class CustomerServiceImpl extends BaseServiceImpl implements ICustomerService {

	private static Logger logger = Logger.getLogger(CustomerServiceImpl.class);

	@Autowired
	private MCustomerMapper customerMapper;

	@Autowired
	private ICustomerExtraService customerExtraService;

	@Autowired
	private ICustomerFamilyService customerFamilyService;

	@Autowired
	private DicClientAPI dicClientAPI;

	@Autowired
	private ChannelClientAPI channelClientAPI;

	@Autowired
	private IAnalysisService analysisService;

	@Override
	public ResultDO add(CustomerDO domain) {

		boolean isFirst = false;

		MCustomer entity = new MCustomer();
		ResultDO result = BeanUtilsExtends.copy(entity, domain);

		if (!result.isSuccess()) {
			result.setSuccess(false);
			return result;
		}

		if (StringUtils.isNotEmpty(domain.getCustomerFemaleName())) {
			// 有女主时，女主为客户首要联系人
			entity.setCustomerName(domain.getCustomerFemaleName());
			entity.setMobileNumber(domain.getMobileFemaleNumber());
			entity.setAppellation(1); // 女士
		} else if (StringUtils.isNotEmpty(domain.getCustomerMaleName())) {
			// 无女主，有男主时男主为首要联系人
			entity.setCustomerName(domain.getCustomerMaleName());
			entity.setMobileNumber(domain.getMobileMaleNumber());
			entity.setAppellation(2); // 先生
		}
		// 客户电话号码查重
		if (checkDuplicate(entity.getMobileNumber())) {
			result.setSuccess(false);
			result.setErrorMsg("客户电话号码重复");
			return result;
		}

		int r = -1;

		entity.setIsMember(0);
		entity.setIsDelete(1);
		entity.setCreatetime(Calendar.getInstance().getTime());
		entity.setModifitime(entity.getCreatetime());
		try {
			r = customerMapper.insertSelective(entity);
		} catch (Exception e) {
			e.printStackTrace();
			r = -1;
		}
		if (r < 0) {
			result.setSuccess(false);
		}

		if (StringUtils.isNotEmpty(domain.getCustomerFemaleName())) {

			CustomerFamilyDO domain2 = new CustomerFamilyDO();
			domain2.setCustomerId(entity.getId());
			domain2.setName(domain.getCustomerFemaleName());
			domain2.setTelephone(domain.getMobileFemaleNumber());
			domain2.setAge(0);
			domain2.setGender(MemberConstant.GENDER_FEMAIL);
			domain2.setIsFirst(MemberConstant.FAMILY_IS_FIRST);
			ResultDO res = customerFamilyService.add(domain2);
			if (!res.isSuccess()) {
				result.setSuccess(false);
				return result;
			}
			isFirst = true;
		}

		if (StringUtils.isNotEmpty(domain.getCustomerMaleName())) {

			CustomerFamilyDO domain2 = new CustomerFamilyDO();
			domain2.setCustomerId(entity.getId());
			domain2.setName(domain.getCustomerMaleName());
			domain2.setTelephone(domain.getMobileMaleNumber());
			domain2.setAge(0);
			domain2.setGender(MemberConstant.GENDER_MEN);
			domain2.setIsFirst(isFirst ? MemberConstant.FAMILY_IS_OTHER : MemberConstant.FAMILY_IS_FIRST);
			ResultDO res = customerFamilyService.add(domain2);
			if (!res.isSuccess()) {
				result.setSuccess(false);
				return result;
			}
		}

		CustomerExtraDO domain3 = new CustomerExtraDO();
		domain3.setId(entity.getId());
		domain3.setConsumeMoney(new BigDecimal(0.00));
		customerExtraService.add(domain3);

		result.setModel(ResultSupport.FIRST_MODEL_KEY, getCustomerDO(entity));
		return result;
	}

	/** 客户电话查重： true-重复； false-不重复 */
	public boolean checkDuplicate(String mobile) {

		MCustomerExample example = new MCustomerExample();
		MCustomerExample.Criteria criteria = example.createCriteria();
		criteria.andMobileNumberEqualTo(mobile);
		criteria.andIsDeleteEqualTo(MemberConstant.DB_ISDEL_NO);

		int count = customerMapper.countByExample(example);

		return count > 0 ? true : false;
	}

	@Override
	public ResultDO remove(Integer[] ids) {

		ResultDO result = new ResultSupport();
		for (Integer id : ids) {
			ResultDO res = remove(id);
			if (!res.isSuccess()) {
				result.setSuccess(false);
				return result;
			}
		}
		return result;
	}

	@Override
	public ResultDO remove(Integer id) {

		ResultDO result = new ResultSupport();
		MCustomer entity = new MCustomer();
		int r = -1;

		entity.setId(id);
		entity.setIsDelete(MemberConstant.DB_ISDEL_YES);

		try {
			r = customerMapper.updateByPrimaryKeySelective(entity);
		} catch (Exception e) {
			e.printStackTrace();
			r = -1;
		}

		if (r < 0) {
			result.setSuccess(false);
		}

		return result;
	}

	@Override
	public ResultDO modifi(CustomerDO domain) {

		MCustomer entity = new MCustomer();
		ResultDO result = BeanUtilsExtends.copy(entity, domain);

		if (!result.isSuccess()) {
			result.setSuccess(false);
			return result;
		}

		ResultDO res = customerFamilyService.get(domain.getCustomerFamilyId());
		CustomerFamilyDO domain2 = (CustomerFamilyDO) res.getModel(ResultSupport.FIRST_MODEL_KEY);
		int r = -1;
		entity.setCustomerName(domain2.getName());
		entity.setMobileNumber(domain2.getTelephone());
		entity.setModifitime(Calendar.getInstance().getTime());
		entity.setAppellation(domain2.getGender());
		try {
			r = customerMapper.updateByPrimaryKeySelective(entity);
		} catch (Exception e) {
			e.printStackTrace();
			r = -1;
		}

		if (r < 0) {
			result.setSuccess(false);
		}

		return result;
	}

	@Override
	public ResultDO get(Integer id) {

		ResultDO result = new ResultSupport();

		MCustomer entity = null;

		Map<String, Object> data = new HashMap<String, Object>();

		try {
			entity = customerMapper.selectByPrimaryKey(id);
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (entity == null) {
			result.setSuccess(false);
			return result;
		}
		CustomerDO domain = getCustomerDO(entity);
		ResultDO res = customerExtraService.get(id);
		if (!res.isSuccess()) {
			result.setSuccess(false);
			logger.error("customerExtraService error");
			return result;
		}
		CustomerExtraDO domain2 = (CustomerExtraDO) res.getModel(ResultSupport.FIRST_MODEL_KEY);
		data.put("customerDO", domain);
		data.put("customerExtraDO", domain2);
		result.setModel(ResultSupport.FIRST_MODEL_KEY, data);
		return result;
	}

	@Override
	public ResultDO query(CustomerQueryDO query) {

		MCustomerExample example = new MCustomerExample();
		ResultDO result = new ResultSupport();
		List<MCustomer> list = null;
		Criteria criteria = example.createCriteria();

		if (query.getNameOrTel() != null) {
			if (StringUtils.isNumeric(query.getNameOrTel())) {
				criteria.andMobileNumberLike("%" + query.getNameOrTel() + "%");
			} else {
				criteria.andCustomerNameLike("%" + query.getNameOrTel() + "%");
			}
		}
		if (StringUtils.isNotEmpty(query.getProvince())) {
			criteria.andProvinceEqualTo(query.getProvince());
		}
		if (StringUtils.isNotEmpty(query.getCity())) {
			criteria.andCityEqualTo(query.getCity());
		}
		if (StringUtils.isNotEmpty(query.getDistrict())) {
			criteria.andDistrictEqualTo(query.getDistrict());
		}
		if (StringUtils.isNotEmpty(query.getAddress())) {
			criteria.andAddressLike("%" + query.getAddress() + "%");
		}
		if (query.getChannelType() != null && query.getChannelType() != 0) {
			criteria.andChannelTypeEqualTo(query.getChannelType());
		}
		if (query.getLevel() != null && query.getLevel() != 0) {
			criteria.andLevelEqualTo(query.getLevel());
		}

		if (StringUtils.isNotEmpty(query.getAuthorOrMobile())) {
			if (isChinaPhoneLegal(query.getNameOrTel())) {
				criteria.andEmployeeMobileLike("%" + query.getNameOrTel() + "%");
			} else {
				criteria.andEmployeeNameLike("%" + query.getNameOrTel() + "%");
			}
		}

		if (query.getIsLead() != null && query.getIsLead() == MemberConstant.FLAG_TRUE) {
			LeadQueryDO query2 = new LeadQueryDO();
			query2.setPage(false);
			ResultDO res = analysisService.query(query2);
			if (res.isSuccess()) {
				List<LeadDO> leads = (List<LeadDO>) res.getModel(ResultDO.FIRST_MODEL_KEY);

				ArrayList<Integer> coustmerIds = new ArrayList<Integer>();
				for (LeadDO lead : leads) {
					coustmerIds.add(lead.getCustomerId());
				}
				criteria.andIdIn(coustmerIds);
			}
		}
		List<CustomerExtraDO> extraList = customerExtraService.queryExtra(query);

		if (extraList != null && extraList.size() != 0) {
			List<Integer> customerIds = new ArrayList<Integer>();
			for (CustomerExtraDO extraDO : extraList) {
				customerIds.add(extraDO.getId());
			}
			criteria.andIdIn(customerIds);
		}

		List<CustomerDO> doList = new ArrayList<CustomerDO>();

		if (query.isPage()) {
			example.setLimitByPage(query.getStart() + "," + query.getPageRows());
			long count = customerMapper.countByExample(example);
			result.setModel(ResultSupport.SECOND_MODEL_KEY, count);
		}

		try {
			list = customerMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg(ResultDO.SYSTEM_EXCEPTION_ERROR_MSG + "获取会员信息失败");
			result.setSuccess(false);
			return result;
		}

		doList = getCustomerDOList(list);
		result.setModel(ResultSupport.FIRST_MODEL_KEY, doList);
		return result;
	}

	/**
	 * 对象拷贝单个实体到对象中
	 * 
	 * @param obj
	 * @return 返回DO对象
	 */
	public CustomerDO getCustomerDO(MCustomer entity) {
		CustomerDO dst = new CustomerDO();
		if (entity == null)
			return dst;
		dst = BeanUtilsExtends.copyProperties(dst, entity) ? dst : null;
		dst.setCreateTimeName(entity.getCreatetime().getTime() + "");
		dst.setModifiTimeName(entity.getModifitime().getTime() + "");

		dst.setCustomerFemaleName(entity.getCustomerName());
		dst.setMobileFemaleNumber(entity.getMobileNumber());

		dst.setCustomerName(entity.getCustomerName());
		dst.setMobile(entity.getMobileNumber());

		// channelTypeName
		if (!isNumberInValid(entity.getChannelType()))
			dst.setChannelTypeName(getChannelTypeName(entity.getChannelType()));
		// level
		if (!isNumberInValid(dst.getLevel())) {
			DictionariesDO dicDO = dicClientAPI.get(dst.getLevel());
			if (null != dicDO)
				dst.setLevelName(dicDO.getDataItem());
		}
		// status
		if (null != dst.getStatus()) {
			dst.setStatusName(StaticDicUtil.STATUS_CUSTOMER.get(dst.getStatus()));
		}

		ResultDO resultDO = customerFamilyService.getFirstByCustomerID(dst.getId());
		if (resultDO.isSuccess()) {
			CustomerFamilyDO familyDO = (CustomerFamilyDO) resultDO.getModel(ResultDO.FIRST_MODEL_KEY);
			dst.setCustomerFamilyId(familyDO.getId());
			dst.setGenderName(familyDO.getGenderName());
			dst.setFirstFamilyDO(familyDO);
		}

		return dst;
	}

	public String getChannelTypeName(Integer id) {
		ChannelTypeDO channelTypeDO = channelClientAPI.getChannelType(id);
		return channelTypeDO == null ? null : channelTypeDO.getChannelName();

	}

	/**
	 * 对象拷贝多个实体到列表中
	 * 
	 * @param List
	 * @return List
	 */
	public List<CustomerDO> getCustomerDOList(List<MCustomer> list) {
		List<CustomerDO> result = new ArrayList<CustomerDO>();
		if (list != null && !list.isEmpty()) {
			for (MCustomer entity : list) {
				CustomerDO domain = getCustomerDO(entity);
				if (domain != null) {
					result.add(domain);
				}
			}
		}
		return result;
	}

	public static boolean isChinaPhoneLegal(String str) throws PatternSyntaxException {
		String regExp = "^((13[0-9])|(14[5-9]|(15[^4])|(166)|(17[0-8])|(18[0-9])|(19[8,9])))\\d{8}$";
		Pattern p = Pattern.compile(regExp);
		Matcher m = p.matcher(str);
		return m.matches();
	}
}
